package com.jeeplus.modules.api.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

public class PgwTraderRSAUtil {
	private static Logger log = Logger.getLogger(PgwTraderRSAUtil.class);
	private static PgwTraderRSAUtil instance;

	public static PgwTraderRSAUtil getInstance() {
		if (instance == null) {
			return new PgwTraderRSAUtil();
		}
		return instance;
	}

	/**
	 * 生产秘钥对
	 * 
	 * @param key_path
	 * @param name_prefix
	 */
	private void generateKeyPair(String key_path, String name_prefix) {
		KeyPairGenerator keygen = null;
		try {
			keygen = KeyPairGenerator.getInstance("RSA");
		} catch (NoSuchAlgorithmException e1) {
			log.error(e1.getMessage());
		}
		SecureRandom secrand = new SecureRandom();
		secrand.setSeed("3500".getBytes());
		keygen.initialize(1024, secrand);
		KeyPair keys = keygen.genKeyPair();
		PublicKey pubkey = keys.getPublic();
		PrivateKey prikey = keys.getPrivate();

		String pubKeyStr = new String(Base64.encodeBase64(pubkey.getEncoded()));
		String priKeyStr = new String(Base64
				.encodeBase64(Base64.encodeBase64(prikey.getEncoded())));
		File file = new File(key_path);
		if (!file.exists()) {
			file.mkdirs();
		}
		try {
			FileOutputStream fos = new FileOutputStream(new File(key_path + name_prefix + "_RSAKey_private.txt"));
			fos.write(priKeyStr.getBytes());
			fos.close();

			fos = new FileOutputStream(new File(key_path + name_prefix + "_RSAKey_public.txt"));
			fos.write(pubKeyStr.getBytes());
			fos.close();
		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * 读取秘钥文件
	 * 
	 * @param key_file
	 * @return
	 */
	private static String getKeyContent(String key_file) {
		File file = new File(key_file);
		BufferedReader br = null;
		InputStream ins = null;
		StringBuffer sReturnBuf = new StringBuffer();
		try {
			ins = new FileInputStream(file);
			br = new BufferedReader(new InputStreamReader(ins, "UTF-8"));
			String readStr = null;
			readStr = br.readLine();
			while (readStr != null) {
				sReturnBuf.append(readStr);
				readStr = br.readLine();
			}
		} catch (IOException e) {
			return null;
		} finally {
			if (br != null) {
				try {
					br.close();
					br = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (ins != null) {
				try {
					ins.close();
					ins = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return sReturnBuf.toString();
	}

	/**
	 * 私钥签名
	 * 
	 * @param prikeyvalue
	 * @param sign_str
	 * @return
	 */
	public static String sign(String prikeyvalue, String sign_str) {
		try {
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(prikeyvalue));
			KeyFactory keyf = KeyFactory.getInstance("RSA");
			PrivateKey myprikey = keyf.generatePrivate(priPKCS8);
			Signature signet = Signature.getInstance("MD5withRSA");
			signet.initSign(myprikey);
			signet.update(sign_str.getBytes("UTF-8"));
			byte[] signed = signet.sign();
			return new String(Base64.encodeBase64(signed));
		} catch (Exception e) {
			log.error("签名失败," + e.getMessage());
		}
		return null;
	}

	/**
	 * 验证签名
	 * 
	 * @param pubkeyvalue
	 * @param oid_str
	 * @param signed_str
	 * @return
	 */
	public static boolean checksign(String pubkeyvalue, String oid_str, String signed_str) {
		try {
			X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(pubkeyvalue));
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PublicKey pubKey = keyFactory.generatePublic(bobPubKeySpec);
			byte[] signed = Base64.decodeBase64(signed_str);
			Signature signetcheck = Signature.getInstance("MD5withRSA");
			signetcheck.initVerify(pubKey);
			signetcheck.update(oid_str.getBytes("UTF-8"));
			return signetcheck.verify(signed);
		} catch (Exception e) {
			log.error("签名验证异常," + e.getMessage());
		}
		return false;
	}
	
	public static void main(String[] args) {
		String data = "codeNo=A3018134647185934594037&mchtNo=454581007631000&orderDate=1023&orderTime=102001&outOrderNo=20181023190800005&requestBranchCode=0200000000032&secMchtNo=&termNo=J5800008&txnAmt=000000000001";
		String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJXyXQRPFz+0jVDkMSnrHNvtg+nY2d3qzB8Akzs+57WPb90cWvSPFO9ji6bkgVqeyhdTcnAoRsoxtSS4naPxJQ/BUjoWfFW5753z2Rpp3HQ7FUpVhNXZMkmq+QNqDmKUUGNrIoWn9PNesc6n4RJMRr2OnQCVoFop1n8OmQKorenDAgMBAAECgYBeaSuH+wR4aAZSWFtcOV0CXJoiMxd6UswS+Rm6w/DAsH+OiLv8H9ren57ehiGsHS7BYRk85R8tT/7uEA+xmbPrL79XZqP8ETYjcwuLQ6yvfdsr8sz1KUtAdgjlbenoq8ykaD6yAYDkvyIHnpVjBEYAls/U/keR2SE1WiuiYpHeAQJBANe85a26SLngTLSk9Lk5mzap+D7XlXLSeQtWiwyD6PTUAoDawEAdqufSnvOuXTyGaKpa/N4JyffkXXoiaPo1+tECQQCx7jmrl0Bi6ZGDNI4FQiVJCxLe1eZtt5o4JO4mDo287yAqSTJL1KnXabdLMjN2iDe6Xbwo99cp/F1ddx41ihhTAkEAx1WoOk8nJ2fSOA86d3J8sZN25km3srI6WXmLXPL86kqCTaDRhexjn3OCntF7IJNoXg9YGaidzshYfqMQsC/0IQJAXspNCu7/LDLGhKGg74g3mNw/Z1uI8PaZQEPcY4XpWLgD6MMp+mAHQ21casEJzaHwHmcFcMXoaMO7camd/GPfZQJAK6ZzzWHNO/oo8TWmSLExTgQHhmypoQGccTJLs1a80JO26eJejwGm1u30gJ42UqDnmCZ+7hjUnnXYDj3270S0hg==";
		String val = sign(priKey, data);
		System.out.println(val);
	}
}
